package com.tedu.weibo.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

/**
 * 用于为所有Controller处理请求的方法记录日志
 * 需求：
 * 在调用Controller处理请求的方法前，记录对应方法调用了  @before           log.info
 * 在调用Controller处理请求的方法后，记录对应方法调用了  @afterReturning   log.info
 * 如果方法出现异常，记录异常信息                      @afterThrowing    log.error
 *
 * 在当前类中添加三个注解，表明当前类为切面类
 * 定义三个切入方法，每个方法中记录日志
 * 在切入点注解上描述切入点信息（每个Controller的每个方法上都要进行）
 * */
@Aspect
@Component
@Slf4j
public class LogAspect {
    @Before(
            value = "execution(public * com.tedu.weibo.controller.*.*(..))"
    )
    public void before(JoinPoint joinPoint){
        String className = joinPoint.getTarget().getClass().getSimpleName();
        String methodName = joinPoint.getSignature().getName();
        log.info("调用"+className+"."+methodName+"()方法执行开始");
    }
    @AfterReturning(
            value = "execution(public * com.tedu.weibo.controller.*.*(..))",
            returning = "returnValue"
    )
    public void afterReturning(JoinPoint joinPoint,Object returnValue){
        String className = joinPoint.getTarget().getClass().getSimpleName();
        String methodName = joinPoint.getSignature().getName();
        log.info("调用"+className+"."+methodName+"()方法执行结束,返回值："+returnValue);
    }
    @AfterThrowing(
            value = "execution(public * com.tedu.weibo.controller.*.*(..))",
            throwing = "e"
    )
    public void afterThrowing(JoinPoint joinPoint,Exception e){
        log.error(e.getMessage(),e);
    }
}
